/*
 * NoIdentificadosDAO.java
 *
 * Created on 9 de febrero de 2007, 02:34 PM
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package com.src.computec.facturacion.noidentificados.dao;
import com.src.computec.facturacion.base.constantes.ConstantesGenerales;
import static com.src.computec.facturacion.base.constantes.ConstantesGenerales.SCHEMA;
import static com.src.computec.facturacion.base.constantes.ConstantesGenerales.CODIGO_DANE_VACIO;
import com.src.computec.facturacion.noidentificados.dto.MunicipioDestinoClienteDto;
import com.src.computec.facturacion.noidentificados.dto.TipoDestinoClienteDto;
import com.src.computec.facturacion.precosto.dto.ClienteDto;
import com.src.computec.facturacion.precosto.dto.OrdenProcesoDto;
import com.src.computec.radar.base.dao.GenericDAO;
import com.src.computec.radar.base.dao.exception.DAOException;
import com.src.computec.radar.base.ldap.dto.LdapUserDto;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author jlperea
 */
public class NoIdentificadosDAO extends GenericDAO implements BaseNoIdentificadosDAO 
{
    ConstantesGenerales constantesGenerales = ConstantesGenerales.getInstance();    
    
    /** Creates a new instance of CargueDAO */
    public NoIdentificadosDAO() {
    }
    
    public List getOrdenesProcesoByFilter(String filter) throws DAOException 
    {
        Connection con = null;
        PreparedStatement statement = null;
        PreparedStatement statement2 = null;
        
        ResultSet rs = null;
        ResultSet rs2 = null;
        
        List retornoLst = new ArrayList();
        
        try {
            con = getConnectionDB2();
            
            statement = con.prepareStatement("SELECT OP.NUMERO_ORDEN, OP.CODIGO_CLIENTE, C.RAZON_SOCIAL, OP.CODIGO_PRODUCTO, P.DESCRIPCION_PRODUCTO, OP.CICLO, OP.FECHA_PROCESO, OP.NUMERO_FACTURA_COMPUTEC " +
                    "FROM " + SCHEMA + ".ORDEN_PROCESO OP " +
                    "INNER JOIN " + SCHEMA + ".CLIENTE C ON OP.CODIGO_CLIENTE = C.CODIGO_CLIENTE " +
                    "INNER JOIN " + SCHEMA + ".PRODUCTO P ON OP.CODIGO_PRODUCTO = P.CODIGO_PRODUCTO " +
                    "WHERE OP.NUMERO_ORDEN = ? ");
            
            statement2   = con.prepareStatement("SELECT COUNT(T.LLAVE) " +
                                                "FROM " +
                                                "( " +
                                                " SELECT ( (E.CODIGO_DEPARTAMENTO * 1000000) + (E.CODIGO_MUNICIPIO * 1000) + (E.CODIGO_CENTROP) ) AS LLAVE " +
                                                " FROM " + SCHEMA + ".ENVIO E " +
                                                " WHERE E.NUMERO_ORDEN = ? " +
                                                //" AND E.CODIGO_DEPARTAMENTO IS NOT NULL AND E.CODIGO_MUNICIPIO IS NOT NULL AND E.CODIGO_CENTROP IS NOT NULL AND " +
                                                //" NOT ( E.CODIGO_DEPARTAMENTO = ? AND E.CODIGO_MUNICIPIO = ? AND E.CODIGO_CENTROP = ? ) " +
                                                ") T " +
                                                "WHERE T.LLAVE NOT IN " +
                                                "( " +
                                                " SELECT ( (MDC.CODIGO_DEPARTAMENTO * 1000000) + (MDC.CODIGO_MUNICIPIO * 1000) + (MDC.CODIGO_CENTROP) ) AS LLAVE2 " +
                                                " FROM " + SCHEMA + ".MUNICIPIO_DESTINO_CLIENTE MDC " +
                                                " WHERE MDC.CODIGO_CLIENTE = ? " +
                                                ") ");
            
            int indice=0;
            
            statement.setObject(++indice, filter);
            rs = statement.executeQuery();
            
            while(rs.next()) {
                int indice1 = 0;
                
                OrdenProcesoDto ordenProcesoDto = new OrdenProcesoDto();
                ordenProcesoDto.setNumeroOrden(rs.getString(++indice1));
                ordenProcesoDto.setCodigoCliente(rs.getString(++indice1));
                ordenProcesoDto.setRazonSocial(rs.getString(++indice1));
                ordenProcesoDto.setCodigoProducto(rs.getString(++indice1));
                ordenProcesoDto.setDescripcionProducto(rs.getString(++indice1));
                ordenProcesoDto.setCiclo(rs.getString(++indice1));
                ordenProcesoDto.setFechaProceso( ConstantesGenerales.STRING_DATE_FORMAT.format(rs.getDate(++indice1)) );
                ordenProcesoDto.setClosed(rs.getString(++indice1) != null? true: false);
                
                /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                indice1 = 0;
                statement2.setObject(++indice1,ordenProcesoDto.getNumeroOrden());
                //statement2.setObject(++indice1, CODIGO_DANE_VACIO);
                //statement2.setObject(++indice1, CODIGO_DANE_VACIO);
                //statement2.setObject(++indice1, CODIGO_DANE_VACIO); 
                statement2.setObject(++indice1,ordenProcesoDto.getCodigoCliente());
                rs2 = statement2.executeQuery();
                
                if(rs2.next()) 
                {
                    indice1 = 0;                   
                    int numeroEnvios = rs2.getInt(++indice1);
                    ordenProcesoDto.setNumeroNoIdentificados(numeroEnvios);                    
                } 
                /////////////////////////////////////////////////////////////////////////////////////////////////////////////                
                retornoLst.add(ordenProcesoDto);
            }
        } 
        catch (SQLException e) 
        {
            throw new DAOException("NoIdentificadosDAO:getOrdenesProcesoByFilter: " +e.toString(), e);
        } 
        finally 
        {
            closeConnection(statement2,rs2);
            closeConnection(con, statement,rs);
        }
        return retornoLst;
    }
    
    public List getTiposDestinoCliente(ClienteDto clienteDto) throws DAOException 
    {
        Connection con = null;
        PreparedStatement statement = null;
        
        ResultSet rs = null;
        
        List retornoLst = new ArrayList();
        
        try {
            con = getConnectionDB2();
            
            statement = con.prepareStatement("SELECT CODIGO_CLIENTE, CODIGO_TIPO_DESTINO_CLIENTE, NOMBRE_TIPO_DESTINO_CLIENTE FROM " + SCHEMA + ".TIPO_DESTINO_CLIENTE WHERE CODIGO_CLIENTE = ? ORDER BY NOMBRE_TIPO_DESTINO_CLIENTE ASC");
                  
            int indice = 0;
            
            statement.setObject(++indice, clienteDto.getCodigoCliente());
            rs = statement.executeQuery();
            
            while(rs.next()) 
            {
                int indice1 = 0;
                
                TipoDestinoClienteDto tipoDestinoClienteDto = new TipoDestinoClienteDto();
                tipoDestinoClienteDto.setCodigoCliente(rs.getString(++indice1));
                tipoDestinoClienteDto.setCodigoTipoDestinoCliente(rs.getString(++indice1));
                tipoDestinoClienteDto.setNombreTipoDestinoCliente(rs.getString(++indice1));
                
                retornoLst.add(tipoDestinoClienteDto);
            }
        } 
        catch (SQLException e) 
        {
            throw new DAOException("NoIdentificadosDAO:getTiposDestinoCliente: " +e.toString(), e);
        } 
        finally 
        {
            closeConnection(con, statement,rs);
        }
        return retornoLst;
    }
    
    public List getDestinosNoIdentificadosByOrdenProceso(OrdenProcesoDto ordenProcesoDto)  throws DAOException
    {
        Connection con = null;
        PreparedStatement statement = null;
        
        ResultSet rs = null;
        
        List retornoLst = new ArrayList();
        
        try {
            con = getConnectionDB2();
            
            statement    = con.prepareStatement("SELECT T.CODIGO_DEPARTAMENTO, T.CODIGO_MUNICIPIO, T.CODIGO_CENTROP, DEP.NOMBRE_DEPARTAMENTO, MUN.NOMBRE_MUNICIPIO, CP.NOMBRE_CENTRO_POBLADO " +
                                                "FROM " +
                                                "( " +
                                                " SELECT ( (E.CODIGO_DEPARTAMENTO * 1000000) + (E.CODIGO_MUNICIPIO * 1000) + (E.CODIGO_CENTROP) ) AS LLAVE, " +
                                                " E.CODIGO_DEPARTAMENTO AS CODIGO_DEPARTAMENTO, E.CODIGO_MUNICIPIO AS CODIGO_MUNICIPIO, E.CODIGO_CENTROP AS CODIGO_CENTROP " +
                                                " FROM " + SCHEMA + ".ENVIO E " +
                                                " WHERE E.NUMERO_ORDEN = ? " +
                                                //" AND E.CODIGO_DEPARTAMENTO IS NOT NULL AND E.CODIGO_MUNICIPIO IS NOT NULL AND E.CODIGO_CENTROP IS NOT NULL AND " +
                                                //" NOT ( E.CODIGO_DEPARTAMENTO = ? AND E.CODIGO_MUNICIPIO = ? AND E.CODIGO_CENTROP = ? ) " +
                                                ") T " +
                                                "INNER JOIN " + SCHEMA + ".DEPARTAMENTO DEP ON DEP.CODIGO_DEPARTAMENTO = T.CODIGO_DEPARTAMENTO " +
                                                "INNER JOIN " + SCHEMA + ".MUNICIPIO MUN ON MUN.CODIGO_MUNICIPIO = T.CODIGO_MUNICIPIO AND MUN.CODIGO_DEPARTAMENTO = T.CODIGO_DEPARTAMENTO " +
                                                "INNER JOIN " + SCHEMA + ".CENTRO_POBLADO CP ON CP.CODIGO_MUNICIPIO = T.CODIGO_MUNICIPIO AND CP.CODIGO_CENTROP = T.CODIGO_CENTROP  AND CP.CODIGO_DEPARTAMENTO = T.CODIGO_DEPARTAMENTO " +
                                                "WHERE T.LLAVE NOT IN " +
                                                "( " +
                                                " SELECT ( (MDC.CODIGO_DEPARTAMENTO * 1000000) + (MDC.CODIGO_MUNICIPIO * 1000) + (MDC.CODIGO_CENTROP) ) AS LLAVE2 " +
                                                " FROM " + SCHEMA + ".MUNICIPIO_DESTINO_CLIENTE MDC " +
                                                " WHERE MDC.CODIGO_CLIENTE = ? " +
                                                ") " +
                                                "GROUP BY T.CODIGO_DEPARTAMENTO, T.CODIGO_MUNICIPIO, T.CODIGO_CENTROP, DEP.NOMBRE_DEPARTAMENTO, MUN.NOMBRE_MUNICIPIO, CP.NOMBRE_CENTRO_POBLADO " +
                                                "ORDER BY DEP.NOMBRE_DEPARTAMENTO, MUN.NOMBRE_MUNICIPIO, CP.NOMBRE_CENTRO_POBLADO ");
                  
            int indice = 0;
            
            statement.setObject(++indice,ordenProcesoDto.getNumeroOrden());
            //statement.setObject(++indice, CODIGO_DANE_VACIO);
            //statement.setObject(++indice, CODIGO_DANE_VACIO);
            //statement.setObject(++indice, CODIGO_DANE_VACIO); 
            statement.setObject(++indice,ordenProcesoDto.getCodigoCliente());
            rs = statement.executeQuery();
            
            while(rs.next()) 
            {
                int indice1 = 0;
                
                MunicipioDestinoClienteDto municipioDestinoClienteDto = new MunicipioDestinoClienteDto();
                municipioDestinoClienteDto.setCodigoCliente(ordenProcesoDto.getCodigoCliente());
                
                municipioDestinoClienteDto.setCodigoDepartamento(rs.getString(++indice1));
                municipioDestinoClienteDto.setCodigoMunicipio(rs.getString(++indice1));
                municipioDestinoClienteDto.setCodigoCentroP(rs.getString(++indice1));
                municipioDestinoClienteDto.setNombreDepartamento(rs.getString(++indice1));
                municipioDestinoClienteDto.setNombreMunicipio(rs.getString(++indice1));                
                municipioDestinoClienteDto.setNombreCentroP(rs.getString(++indice1));
                
                retornoLst.add(municipioDestinoClienteDto);
            }
        } 
        catch (SQLException e) 
        {
            throw new DAOException("NoIdentificadosDAO:getDestinosNoIdentificadosByOrdenProceso: " +e.toString(), e);
        } 
        finally 
        {
            closeConnection(con, statement,rs);
        }
        return retornoLst;
    }
    
    public TipoDestinoClienteDto getTipoDestinoClienteByPrimaryKey(TipoDestinoClienteDto tipoDestinoClienteDto) throws DAOException 
    {
        Connection con = null;
        PreparedStatement statement = null;
        
        ResultSet rs = null;
        
        try {
            con = getConnectionDB2();
            
            statement = con.prepareStatement("SELECT NOMBRE_TIPO_DESTINO_CLIENTE FROM " + SCHEMA + ".TIPO_DESTINO_CLIENTE WHERE CODIGO_CLIENTE = ? AND CODIGO_TIPO_DESTINO_CLIENTE = ? ");
                  
            int indice = 0;
            
            statement.setObject(++indice, tipoDestinoClienteDto.getCodigoCliente());
            statement.setObject(++indice, tipoDestinoClienteDto.getCodigoTipoDestinoCliente());
            rs = statement.executeQuery();
            
            if(rs.next()) 
            {
                int indice1 = 0;                
                tipoDestinoClienteDto.setNombreTipoDestinoCliente(rs.getString(++indice1));                
            }
        } 
        catch (SQLException e) 
        {
            throw new DAOException("NoIdentificadosDAO:getTipoDestinoClienteByPrimaryKey: " +e.toString(), e);
        } 
        finally 
        {
            closeConnection(con, statement,rs);
        }
        return tipoDestinoClienteDto;
    }
    
    public List identificarDestinos(List listaNoIdentificados, LdapUserDto ldapUserDto) throws DAOException 
    {
        Connection con = null;
        PreparedStatement statement = null;
        PreparedStatement statement2 = null;
        
        List retornoLst = new ArrayList();
        
        try 
        {
            con = getConnectionDB2();
            
            statement = con.prepareStatement("INSERT INTO " + SCHEMA + ".MUNICIPIO_DESTINO_CLIENTE (CODIGO_CLIENTE,CODIGO_MUNICIPIO,CODIGO_CENTROP,CODIGO_DEPARTAMENTO,CODIGO_TIPO_DESTINO_CLIENTE) VALUES (?,?,?,?,?) ");
            statement2 = con.prepareStatement("INSERT INTO "+SCHEMA+".TIPO_DESTINO_CLIENTE_LOG (CODIGO_RESPONSABLE,FECHA_MODIFICACION,CODIGO_CLIENTE,CODIGO_DEPARTAMENTO,CODIGO_MUNICIPIO,CODIGO_CENTROP,CODIGO_TDC_ANTERIOR,CODIGO_TDC_NUEVO) " +
                                              "VALUES (?,?,?,?,?,?,?,?)");
            
            Iterator iterator = listaNoIdentificados.iterator();
            
            while(iterator.hasNext())
            {
                MunicipioDestinoClienteDto auxMunicipioDestinoClienteDto = (MunicipioDestinoClienteDto)iterator.next();   
                
                int indice = 0;
                statement.setObject(++indice, auxMunicipioDestinoClienteDto.getCodigoCliente());
                statement.setObject(++indice, auxMunicipioDestinoClienteDto.getCodigoMunicipio());
                statement.setObject(++indice, auxMunicipioDestinoClienteDto.getCodigoCentroP());
                statement.setObject(++indice, auxMunicipioDestinoClienteDto.getCodigoDepartamento());                
                statement.setObject(++indice, auxMunicipioDestinoClienteDto.getCodigoTipoDestinoCliente());
                statement.executeUpdate(); 
                
                indice = 0;
                statement2.setObject(++indice, ldapUserDto.getIdLdap());
                statement2.setTimestamp(++indice,new Timestamp(System.currentTimeMillis()));
                statement2.setInt(++indice, Integer.parseInt(auxMunicipioDestinoClienteDto.getCodigoCliente()));
                statement2.setInt(++indice, Integer.parseInt(auxMunicipioDestinoClienteDto.getCodigoDepartamento()));
                statement2.setInt(++indice, Integer.parseInt(auxMunicipioDestinoClienteDto.getCodigoMunicipio()));
                statement2.setInt(++indice, Integer.parseInt(auxMunicipioDestinoClienteDto.getCodigoCentroP()));
                statement2.setInt(++indice, 0);
                statement2.setInt(++indice, Integer.parseInt(auxMunicipioDestinoClienteDto.getCodigoTipoDestinoCliente()));
                statement2.executeUpdate(); 
                
                auxMunicipioDestinoClienteDto.setCorrected(true);
                retornoLst.add(auxMunicipioDestinoClienteDto);
            }            
        } 
        catch (SQLException e) 
        {
            throw new DAOException("NoIdentificadosDAO:identificarDestinos: " +e.toString(), e);
        } 
        finally 
        {
            closeConnection(null, statement2);
            closeConnection(con, statement);
        }
        return retornoLst;
    }    
}
